import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.*;

public class TwinkleApp {
	List<Element> elementList = new ArrayList<Element>();
	JFrame screen = new JFrame("Twinkle Application");
	TPanel panel = new TPanel();
	TKeyListener keyListener = new TKeyListener(this);

	volatile boolean isWorking = false;

	// #
	int key;

	// ##
	public TwinkleApp() {
		display();
		screen.setBackground(Color.white);
		screen.addKeyListener(keyListener);
		screen.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		screen.setResizable(true);
		screen.getContentPane().add(panel);
		screen.pack();
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		screen.setSize(screenSize);
	}

	public void clearKeys() {
		keyListener.reset();
	}

	/** This method should be called when we say start activity.. */
	public void display() {
		screen.setVisible(true);
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void waitFor(long timeInSec) {
		try {
			Thread.sleep(timeInSec * 1000);
		} catch (InterruptedException e) {
			System.out.println("" + e);
		}
	}

	public synchronized void show(Element element) {

		clearKeys();
		System.out.println("in here");
		panel.displayImageAndText(element.getImageFile(), element
				.getElementName(), element.getColor());

		String sound = element.getSoundFile();
		panel.playSound(sound);
	}

	public synchronized void show(Element element, long timeInSec) {
		clearKeys();
		System.out.println("\n **JAVA invoking show with "+ " name=" + element.getElementName() + " "
				+ element.getImageFile() + " sound=" + element.getSoundFile()
				+ " color=" + element.getColor());
		show(element);
		waitFor(timeInSec);
		panel.clearPanel();
	}

	public synchronized void show(String word, String image, String sound,
			String color) {
		show(new Element(word, image, sound, color));
	}

	public synchronized List<Integer> getShuffledList(int size) {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < size; i++) {
			list.add(i);
		}
		Collections.shuffle(list);
		return list;
	}

	public synchronized void showAll(ArrayList<String> word,
			ArrayList<String> image, ArrayList<String> sound,
			ArrayList<String> color, long timeInSec) {
		waitToComplete();
		clearKeys();
		for (Integer i : getShuffledList(word.size())) {
			Element element = new Element(word.get(i), image.get(i), sound
					.get(i), color.get(i));

			show(element);
			waitFor(timeInSec);
		}
		notifyOthers();
	}

	public synchronized void showIfPressed(ArrayList<String> word,
			ArrayList<String> image, ArrayList<String> sound,
			ArrayList<String> color, ArrayList<String> key, long waitTimeInSec) {
		waitToComplete();
		clearKeys();
		for (int i = 0; i < key.size(); i++) {
			String key2 = key.get(i);
			String word2 = word == null ? "" : word.get(i);
			String image2 = image == null ? "" : image.get(i);
			String sound2 = sound == null ? "" : sound.get(i);
			String color2 = color == null ? "" : color.get(i);
			addElement(key2, word2, image2, sound2, color2);
		}
		
		waitFor(waitTimeInSec);
		notifyOthers();
	}

	public synchronized void showIfPressed(String word, String image,
			String sound, String color, String key, int waitTimeInSec) {
		waitToComplete();
		clearKeys();
		addElement(key, word, image, sound, color);

		notifyOthers();
		waitFor(waitTimeInSec);
		//System.out.println("over waiting");
	}

	public synchronized void showAndTest(final ArrayList<String> names,
			final ArrayList<String> images, ArrayList<String> colors,
			String questionSound, final ArrayList<String> answerSound,
			final ArrayList<String> keys) {
		
		waitToComplete();
		clearKeys();
		for (Integer i : getShuffledList(names.size())) {
			String color = colors == null ? null : colors.get(i);
			String name = names == null ? "" : names.get(i);
			String image = images == null ? "" : images.get(i);
			questionSound = questionSound == null ? "" : questionSound;

			show("", image, questionSound, color);
			String keyText = KeyEvent.getKeyText(keyListener.getKeyTyped());
			while (!keyText.equals(keys.get(i))) {
				show("", image, "tryagain.wav", color);
				keyText = KeyEvent.getKeyText(keyListener.getKeyTyped());
			}
			String ansSound = answerSound == null ? "" : answerSound.get(i);
			show(name, image, ansSound, color);
			waitFor(2);
		}
		notifyOthers();
	}

	public synchronized void showMessage(String message, String color) {
		waitToComplete();
		clearKeys();
		System.out.println("show Message " + message);
		panel.drawCenteredString(message, color);
		notifyOthers();
	}

	public synchronized void showMessage(String message) {
		waitToComplete();
		clearKeys();
		System.out.println("showMessage " + message);
		panel.drawCenteredString(message, "green");
		notifyOthers();
	}

	public synchronized void sayFile(String file) {
		waitToComplete();
		panel.playSound(file);
		notifyOthers();

	}

	public synchronized void say(String sound) {
		waitToComplete();
		System.out.println("Say " + sound);
		panel.playSound(sound);
		notifyOthers();
	}

	public synchronized void sayIt(String file) {
		waitToComplete();
		panel.sayIt(file);
		notifyOthers();
	}

	private void addElement(String key, String word, String image,
			String sound, String color) {
		System.out.println("adding element " + key + " " + word + " " + image
				+ " " + sound + " " + color);
		keyListener.addElement(key, word, image, sound, color);
	}

	public void addElement(String key, String word, String image, String sound) {
		System.out.println("adding element " + key + " " + word + " " + image
				+ " " + sound + " ");
		keyListener.addElement(key, word, image, sound);
	}

	public TPanel getTPanel() {
		return panel;
	}

	public TKeyListener getKeyListener() {
		return keyListener;
	}

	public void addKeyListener(KeyListener listener) {
		screen.addKeyListener(listener);
	}

	public static String convertKeyCodeToString(int keyCode) {
		return KeyEvent.getKeyText(keyCode);
	}

	public void waitToComplete() {
		if (!isWorking) {
			return;
		}
		try {
			wait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		isWorking = true;
	}

	public void notifyOthers() {
		isWorking = false;
		notifyAll();
	}

	public boolean hasKeyElements() {
		return keyListener.hasKeyElements();
	}

	// #

	public synchronized int keyNo(char s) {
		
		s=Character.toLowerCase(s);
		int x = 0;
		
		switch (s) {
		case '1':
			x = 49;
			break;
		case '2':
			x = 50;
			break;
		case '3':
			x = 51;
			break;
		case '4':
			x = 52;
			break;
		case '5':
			x = 53;
			break;
		case '6':
			x = 54;
			break;
		case '7':
			x = 55;
			break;
		case '8':
			x = 56;
			break;
		case '9':
			x = 57;
			break;
		case '0':
			x = 48;
			break;
		case 'a':
			x = 65;
			break;
		case 'b':
			x = 66;
			break;
		case 'c':
			x = 67;
			break;
		case 'd':
			x = 68;
			break;
		case 'e':
			x = 69;
			break;
		case 'f':
			x = 70;
			break;
		case 'g':
			x = 71;
			break;
		case 'h':
			x = 72;
			break;
		case 'i':
			x = 73;
			break;
		case 'j':
			x = 74;
			break;
		case 'k':
			x = 75;
			break;
		case 'l':
			x = 76;
			break;
		case 'm':
			x = 77;
			break;
		case 'n':
			x = 78;
			break;
		case 'o':
			x = 79;
			break;
		case 'p':
			x = 80;
			break;
		case 'q':
			x = 81;
			break;
		case 'r':
			x = 82;
			break;
		case 's':
			x = 83;
			break;
		case 't':
			x = 84;
			break;
		case 'u':
			x = 85;
			break;
		case 'v':
			x = 86;
			break;
		case 'w':
			x = 87;
			break;
		case 'x':
			x = 88;
			break;
		case 'y':
			x = 89;
			break;
		case 'z':
			x = 90;
			break;
		
		}
		return x;

	}

	public synchronized void waitForKey() {
		int keyTyped = keyListener.getKeyTyped();
		System.out.println(" a key is pressed " + keyTyped);
		key = keyTyped;

	}

	// ##

	public synchronized void reset() {
		// System.out.println("Resetting the elements map and listener key map");
		// charElementMap.clear();
		// keyListener.reset();
	}

	// public static void main(String[] args) {
	// TwinkleApp tm = new TwinkleApp();
	// String imageFile = "world.jpg";
	// String soundFile = "helloWorld.wav";
	// tm.addElement("h", "hello world", imageFile, soundFile, "black");
	// tm.display();
	// }

}
